package com.zbcz.erp.viewmodel

import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.os.Environment
import android.provider.OpenableColumns
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.zbcz.erp.ErpApplication
import com.zbcz.erp.bean.FileSavingResponse
import com.zbcz.erp.network.ErpApi
import com.zbcz.erp.network.RetrofitManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileOutputStream

class PdfPreViewViewModel : ViewModel() {

    companion object {
        const val TAG = "PdfPreViewViewModel"
    }

    var fileDownloadedLiveData: MutableLiveData<File?> = MutableLiveData()

    fun downloadPdfFile(downLoadFileUrl: String?, fileName: String?) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                downloadFile(downLoadFileUrl, fileName).collect { response ->
                    if (response.isComplete) {
                        response.file?.let {
                            fileDownloadedLiveData.postValue(response.file)
                        }
                    }
                }
            }
        }
    }

    private suspend fun downloadFile(
        downLoadFileUrl: String?, fileName: String?
    ): Flow<FileSavingResponse> = flow {
        val service = RetrofitManager.getRetrofit().create(ErpApi::class.java)
        val response = service.downloadFile(downLoadFileUrl)
        if (response.isSuccessful) {
            val body = response.body()
            body?.let { responseBody ->
                try {
                    val directory =
                        ErpApplication.mApplication.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)
                    Log.i(TAG, "directory=$directory")
                    if (!directory?.exists()!!) {
                        directory.mkdirs()
                    }
                    val file = File(directory, fileName)
                    Log.i(TAG, "file$file")
                    file.delete()
                    if (!file.exists()) {
                        file.createNewFile()
                    }
                    val bufferSize = 8192
                    val buffer = ByteArray(bufferSize)
                    var totalBytesRead = 0L
                    var fileSize = responseBody.contentLength()

                    if (fileSize == -1L) {
                        fileSize = Long.MAX_VALUE // Set a max value for unknown size
                    }

                    responseBody.byteStream().use { inputStream ->
                        FileOutputStream(file).use { outputStream ->
                            while (true) {
                                val bytesRead = inputStream.read(buffer)
                                if (bytesRead == -1) break

                                outputStream.write(buffer, 0, bytesRead)
                                totalBytesRead += bytesRead.toLong()
                                val progress = if (fileSize != Long.MAX_VALUE) {
                                    ((totalBytesRead.toFloat() / fileSize.toFloat()) * 100).toInt()
                                } else {
                                    ((totalBytesRead.toFloat() / (1024 * 1024)).toInt() * 100) / 100
                                }
                                //Log.i(TAG, "progress=$progress")
                                emit(FileSavingResponse(progress, false, null, fileSize))
                            }
                            emit(FileSavingResponse(100, true, file, fileSize))
                        }
                    }
                } catch (e: Exception) {
                    Log.i(TAG, e.toString())
                    throw e
                }
            }
        } else {
            Log.i(TAG, "response failed")
            throw Exception("HTTP ERROR")
        }
    }.flowOn(Dispatchers.IO)


    suspend fun copyUriToFile(uri: Uri): File? {
        return withContext(Dispatchers.IO) {
            try {
                val contentResolver: ContentResolver = ErpApplication.mApplication.contentResolver
                val fileName = getFileNameFromUri(uri)
                val inputStream = contentResolver.openInputStream(uri)
                val directory =
                    ErpApplication.mApplication.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)
                val file = File(directory, fileName)

                FileOutputStream(file).use { outputStream ->
                    inputStream?.copyTo(outputStream)
                }

                inputStream?.close()
                file
            } catch (e: Exception) {
                Log.e("PdfViewModel", "Error copying URI to file: ${e.message}")
                null
            }
        }
    }

    private fun getFileNameFromUri(uri: Uri): String {
        var fileName = "Unknown"
        ErpApplication.mApplication.contentResolver.query(uri, null, null, null, null)
            ?.use { cursor ->
                if (cursor.moveToFirst()) {
                    val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
                    if (nameIndex >= 0) {
                        fileName = cursor.getString(nameIndex)
                    }
                }
            }
        //fileName.substringBeforeLast(".")
        return fileName
    }
}